/*

The contents of this web application are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this web application except in compliance with the License. 
You may obtain a copy of the License at http://www.mozilla.org/MPL/.

Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
See the License for the specific language governing rights and limitations under the License.

The Original Code is owned by and the Initial Developer of the Original Code is Composite A/S (Danish business reg.no. 21744409). All Rights Reserved

Section 11 of the License is EXPRESSLY amended to include a provision stating that any dispute, including but not limited to disputes related to the enforcement of the License, to which Composite A/S as owner of the Original Code, as Initial Developer or in any other role, becomes a part to shall be governed by Danish law and be initiated before the Copenhagen City Court ("K�benhavns Byret")
                        
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Composite.C1Console.Security;
using Composite.C1Console.Elements;
using Composite.Core.ResourceSystem;
using System.Xml.Linq;
using Composite.Functions;



namespace Composite.C1Console.Trees
{    
    internal sealed class FunctionElementGeneratorTreeNode : TreeNode
    {
        public XElement FunctionMarkup { get; internal set; }   // Requried
        public string Label { get; internal set; }              // Requried
        public string ToolTip { get; internal set; }            // Defaults to Label
        public ResourceHandle Icon { get; internal set; }       // Defaults to 'folder'
        

        // Cached
        private BaseRuntimeTreeNode _functionNode;


        private IEnumerable<KeyValuePair<string, string>> GetFunctionResult()
        {
            return _functionNode.GetValue<IEnumerable<KeyValuePair<string, string>>>(); 
        }




        public override IEnumerable<EntityToken> GetEntityTokens(EntityToken childEntityToken, TreeNodeDynamicContext dynamicContext)
        {
            IEntityTokenContainingParentEntityToken containingParentEnitytToken = childEntityToken as IEntityTokenContainingParentEntityToken;
            if (containingParentEnitytToken != null)
            {
                childEntityToken = containingParentEnitytToken.GetParentEntityToken();
            }


            foreach (EntityToken entityToken in this.ParentNode.GetEntityTokens(childEntityToken, dynamicContext))
            {                
                foreach (var kvp in GetFunctionResult())
                {
                    yield return new TreeFunctionElementGeneratorEntityToken(this.Id, this.Tree.TreeId, EntityTokenSerializer.Serialize(entityToken), kvp.Key);
                }
            }
        }



        public override AncestorResult GetParentEntityToken(EntityToken ownEntityToken, Type parentInterfaceOfInterest, TreeNodeDynamicContext dynamicContext)
        {
            return new AncestorResult(this.ParentNode, ((TreeFunctionElementGeneratorEntityToken)ownEntityToken).ParentEntityToken);
        }



        protected override IEnumerable<Element> OnGetElements(EntityToken parentEntityToken, TreeNodeDynamicContext dynamicContext)
        {
            foreach (var kvp in GetFunctionResult())
            {
                Element element = new Element(new ElementHandle(
                    dynamicContext.ElementProviderName,
                    new TreeFunctionElementGeneratorEntityToken(this.Id.ToString(), this.Tree.TreeId, EntityTokenSerializer.Serialize(parentEntityToken), kvp.Key),
                    dynamicContext.Piggybag.PreparePiggybag(this.ParentNode, parentEntityToken)
                ));

                element.VisualData = new ElementVisualizedData
                {
                    Label = kvp.Value,
                    ToolTip = kvp.Value,
                    HasChildren = ChildNodes.Count() > 0,
                    Icon = Core.ResourceSystem.ResourceHandle.BuildIconFromDefaultProvider("folder"),
                    OpenedIcon = Core.ResourceSystem.ResourceHandle.BuildIconFromDefaultProvider("folder")
                };

                yield return element;
            }
        }



        protected override void OnInitialize()
        {
            //MRJ: DSLTree: FunctionElementGeneratorTreeNode: More validaion here
            //MRJ: DSLTree: FunctionElementGeneratorTreeNode: What kind of return type should the function have?
            _functionNode = FunctionTreeBuilder.Build(this.FunctionMarkup);
        }


        public override string ToString()
        {

            return string.Format("FunctionElementGeneratorTreeNode, Id = {0}, Label = {1}", this.Id, this.Label);
        }
    }
}
